function Validate($,pcCommon){

	/*
	    表单只验证单个
		option{
			validate:
		}
	*/
	$.fn.validateForm = function(option){
		if(this){
			if(this.length==1){
				var option = $.extend({validate:function(){return true;}},option || {});
				var elements = [];
				$(this).find("input").each(function(){
					if(elementInfoProcessor.type(this) != 'button' && elementInfoProcessor.type(this)!='hidden'){
						elements.push(this);
					}
				})
				$(this).find("textarea").each(function(){
					elements.push(this);
				});
				$(this).find("select").each(function(){
					elements.push(this);
				});
				var res = $(elements).validate() && option.validate();
				return res;
			}else{
				alert("只验证单个项目");
			}
		}
		return false;
	}

	$.fn.validate = function(){
		if(this){
			if(this.length > 1){
				var elementInfos = getElementInfo(this);
				var res = true;
				$(elementInfos).each(function(){
					var tmpRes = elementValidate.check(this);
					if(!tmpRes){
						res = tmpRes;
					}
				});
				return res;
			}else{
				var elementInfo = elementValidate.info(this[0]);
				return elementValidate.check(elementInfo);
			}
		}
	}

	/**
	 * [inputForm description]
	 * @param  {[type]} option {withEffect(默认为true)用来设置是否在(input,textarea丢失焦点,select onchange时 进行校验)}
	 */
	$.fn.inputForm = function(option){
		if(this){
			if(this.length == 1){
				new InputForm().init(this);
			}else{
				alert("只验证单个项目");
			}
		}
	}

}

function getElementInfo(elements){
	var elementInfos = [];
	$(elements).each(function(){
		var elementInfo = elementValidate.info(this);
		if(elementInfo){
			if($(elementInfos).filter(function(){
				return elementInfo.tag === this.tag &&  elementInfo.name == this.name && elementInfo.type == this.type;
			}).length == 0){
				elementInfos.push(elementInfo);
			}
		}
	});
	return elementInfos;
}

var InputForm = function(){
	return {
		init:function(formElement,option){
			var _this = this;
			_this.option = $.extend({withEffect:true},option||{});
			_this.requireBtns = $(formElement).find('input[type="button"][require]');
			_this.singleRequireBtns = $(formElement).find('input[type="button"][singleRequire]');
			var elements = [];
			$(formElement).find("input[require]").each(function(){
				if(elementInfoProcessor.type(this) != 'button' && elementInfoProcessor.type(this)!='hidden'){
					elements.push(this);
				}
			});
			$(formElement).find("textarea[require]").each(function(){
				elements.push(this);
			});
			$(formElement).find("select[require]").each(function(){
				elements.push(this);
			});
			_this.elements = elements;
			_this.bindEvents();
		},
		bindEvents:function(){
			var _this = this;
			var elementInfos = getElementInfo(_this.elements);
			$(elementInfos).each(function(){
				if(this.tagName == 'input' || this.tagName == 'textarea'){
					if(this.type ==='checkbox' || this.type === 'radio'){
						$(this.elem).bind("click",function(){
							_this.effectBtns();
							_this.effectValidate(this);
						});
					}
					else{
						$(this.elem).on("blur",function(){
							_this.effectBtns();
							_this.effectValidate(this);
						});

						$(this.elem).bind("input property",function(){
							_this.effectBtns();
						});

						$(this.elem).bind("change",function(){
							_this.effectBtns();
						});
					}	
				}else if(this.tagName == 'select'){
					$(this).bind("change",function(){
						_this.effectBtns();
						_this.effectValidate(this);
					});
				}
			});
		},
		effectValidate:function(elem){
			var _this = this;
			if(_this.option.withEffect){
				$(elem).validate();
			}
		},
		effectBtns:function(){
			var _this = this;
			var elementInfo = getElementInfo(_this.elements);

			var isHasInput = false;
			var hasNoInput = false;
			$(elementInfo).each(function(){
				if(this.val){
					isHasInput = true;
				}else{
					if(this.checked){
						isHasInput = true;
					}else{
						hasNoInput = true;
					}
				}
			});

			if(_this.requireBtns && _this.requireBtns.length > 0){
				$(_this.requireBtns).each(function(){
					if(hasNoInput){
						$(this).prop('disabled', true).removeClass('enable').addClass("disabled");
					}else{
						$(this).prop("disabled", false).addClass('enable').removeClass("disabled");
					}
				});
			}
			if(_this.singleRequireBtns  && _this.singleRequireBtns.length > 0){
				$(_this.singleRequireBtns).each(function(){
					if(!isHasInput){
						$(this).prop('disabled', true).removeClass('enable').addClass("disabled");
					}else{
						$(this).prop("disabled", false).addClass('enable').removeClass("disabled");
					}
				});
			}
		}
	}
}



var ElementValidate = function(){
	return {
		info:function(elem){
			return elementInfoProcessor.get(elem);
		},
		check:function(elementInfo){
			var msg = checkProcessor.check(elementInfo);
			$(elementInfo.elem).parent().find(".tipmessage").text(msg);
			$(elementInfo.elem).parent().siblings(".tipmessage").text(msg);
			return msg==''?true:false;
		}
	}
}

var elementValidate = new ElementValidate();

var ElementInfo = function(){
	return {
		get:function(elem){
			var _this = this;
			if(_this.isCanValidate(elem)){
				var elementInfo = {};
				elementInfo.name = elem.name;
				elementInfo.id = elem.id;
				elementInfo.tagName = _this.tagName(elem);
				elementInfo.type = _this.type(elem);
				elementInfo.validateInfo = _this.validateInfo(elem);
				_this.setElement(elem,elementInfo);
				_this.elementVal(elementInfo);
				return elementInfo;
			}else{
				return null;
			}
		},
		isCanValidate:function(elem){
			var _this = this;
			var validateTagNames = "input,select,textarea";
			
			if(validateTagNames.indexOf(_this.tagName(elem))>=0){
				return true;
			}
			return false;
		},
		type:function(el){
			var type = el.getAttribute("type");
			if (type) {
				var typeReplace = type.replace(/\W+$/, "");	
				if ( type != typeReplace) {
					try { el.type = typeReplace; } catch(e) {}
				}
				type = typeReplace;
			}
			return type;
		},
		tagName:function(elem){
			return elem.tagName.toLowerCase();
		},
		elementVal:function(elementInfo){
			if(elementInfo.tagName === 'input' || elementInfo.tagName === 'textarea'){
				if(elementInfo.type === 'checkbox' || elementInfo.type === 'radio'){
					var sel = 'input[name="' + elementInfo.name + '"]:checked';
					var checked = $(sel);
					if(checked.length > 0){
						elementInfo.checked = true;
						var val = "";
						checked.each(function(){
							val = val + (val == '' ?'':',') + $(this).val();
						})
						elementInfo.val = val;
					}
				}else{
					elementInfo.val = elementInfo.elem.val();
				}
			}else{
				elementInfo.val = elementInfo.elem.val();
			}

		},
		validateInfo:function(el){
			var validateInfo = {};
			if(el.hasAttribute("require"))validateInfo.require=true;
			if(el.hasAttribute("mobile"))validateInfo.mobile=true;
			if(el.hasAttribute("newmobileTip"))validateInfo.newmobileTip=true;
			if(el.hasAttribute("email"))validateInfo.email=true;
			if(el.hasAttribute("number"))validateInfo.number=true;
			if(el.hasAttribute("newPasTip"))validateInfo.newPasTip=true;
			if(el.hasAttribute("letter"))validateInfo.letter=true;
			if(el.hasAttribute("numletter"))validateInfo.numletter=true;
			if(el.hasAttribute("chinese"))validateInfo.chinese=true;
			if(el.hasAttribute("idcard"))validateInfo.idcard=true;
			if(el.hasAttribute("numwith2float"))validateInfo.numwith2float=true;
			if(el.hasAttribute("amount"))validateInfo.amount=true;
			if(el.hasAttribute("nickname"))validateInfo.nickname=true;
			if(el.hasAttribute("phoneMes"))validateInfo.phoneMes=true;
			if($(el).attr("eqTo"))validateInfo.eqTo=$(el).attr("eqTo");
			if($(el).attr("minLen"))validateInfo.minLen=$(el).attr("minLen");
			if($(el).attr("maxLen"))validateInfo.maxLen=$(el).attr("maxLen");
			if($(el).attr("minVal"))validateInfo.minVal=$(el).attr("minVal");
			if($(el).attr("maxVal"))validateInfo.maxVal=$(el).attr("maxVal");
			return validateInfo;
		},
		setElement:function(el,elementInfo){
			elementInfo.elem = $(el);
			if(elementInfo.tagName == 'input'){
				if(elementInfo.type === 'checkbox' || elementInfo.type === 'radio'){
					var eleCheckboxs = elementInfo.name? $("input[type='"+elementInfo.type+"'][name='"+ elementInfo.name +"']"): $(el);
					elementInfo.elem = eleCheckboxs;
				}
			}
		}
	}
}



var CheckProcessor = function(){
	return {
		check:function(elementInfo){
			var _this = this;
			var msg = '';
			for(key in elementInfo.validateInfo){
				msg = _this.proc(key,elementInfo.validateInfo[key],elementInfo);
				if(msg)
					break;
			}
			return msg;
		},
		proc:function(key,ckVal,elementInfo){
			var _this = this;
			var elementVal = elementInfo.val;
			var reg = ValidateOptions.reg[key];
			var elem = elementInfo.elem;
			if(reg){
				if(!_this.checkReg(reg,elementVal)){
					return _this.getMsgByType(elem,key);
				}
			}else{
				if(key === "require"){
					if(!elementVal){
						return _this.getMsgByType(elem,"must");
					}
				}
				else if(key === "minLen" || key === "maxLen"){
					if(!_this.checkLen(key === "minLen"?0:1,ckVal,elementVal)) {
						return _this.getMsgByType(elem,"len");
					}
				}
				else if(key === "minVal" || key === "maxVal"){
					if(!_this.checkVal(key === "minVal"?0:1,ckVal,elementVal)) {
						return _this.getMsgByType(elem,"val");
					}
				}else if(key === "eqTo"){
					if(!_this.checkEq(ckVal,elementVal)){
						return _this.getMsgByType(elem,"eq");
					}
				}
			}
			return "";
		},
		checkReg:function(reg,val){
			try{
				if (val) {
					return reg.test(val);
				}
			}catch(e){
				return false;
			}
			return true;
		},
		checkLen:function(direct,ckValue,value){
			var inputLength = value.length;
			if(direct == 1) //MAX
			{
				if(inputLength > ckValue){
					return false;
				}
			}
			else{
				if(inputLength < ckValue){
					return false;
				}
			}
			return true;
		},
		checkVal:function(direct,ckValue,value){
			value = parseInt($.trim(value));
			if(direct == 1){ //Max
				if(value > ckValue){
					return false;
				}
			}else{
				if(value < ckValue){
					return false;
				}
			}
			return true;
		},
		checkEq:function(target,value){
			var tgVal = $("#" + target).val();
			return tgVal === value;
		},
		getMsgByType:function(element,type)
		{
			var setType = '';
			if(type) setType = type +"Msg";
			var msg = $(element).attr(setType);
			if(!msg){
				msg = $(element).attr("msg");
				if(!msg){
					msg = ValidateOptions.msg[type];
				}
			}
			return $.trim(msg);
		}
	}
};

var elementInfoProcessor = new ElementInfo();
var checkProcessor = new CheckProcessor();

var ValidateOptions = {
	//提示信息
	msg:{
		email   	: '邮箱地址格式不正确',
		number     	: '请填写数字',
		letter      : '请输入字母',
		chinese     : '请填写中文',
		mobile   	: '手机号格式不正确',
		idcard      : '身份证位数不正确',      
		numletter 	: '应该为数字和字母的组合字符',
		passport    : '护照格式有误',
		numwith2float: '请输入最多有两位小数的数字',
		amount       : '金额格式不正确',
		nickname     : '昵称格式不正确',
		phoneMes	 : '手机验证码为6位数字',
		newmobileTip : '请输入正确的手机号',
		newPasTip : '登陆密码格式不正确',
		must:'必须输入'
	},
	reg:{
		email 		: /^\w+\@[a-zA-Z0-9]+\.[a-zA-Z]{2,4}$/i,   //验证邮箱
		number      : /^\d+$/,                                 //验证数字
		letter      : /^[A-Za-z]*$/,						   //验证字母
		chinese     : /^[\u4E00-\u9FA5·]+$/,                    //验证中文
		mobile      : /^1[0-9]{1}[0-9]{9}$/,                 //验证手机
		newmobileTip :/^1[34578]{1}[0-9]{9}$/,                 //验证手机
		idcard      : /^\d{14}\d{3}?\w$/,                      //验证身份证
		numletter   : /^(?=.*[a-zA-Z]+)(?=.*[0-9]+)[a-zA-Z0-9]+$/, 			     //验证数字和字母
		passport    : /^1[45][0-9]{7}|G[0-9]{8}|P[0-9]{7}|S[0-9]{7,8}|D[0-9]+$/, //验证护照
		numwith2float: /^\d+\.?\d{0,2}$/,                                        //带两位小数点数字验证
		amount       : /^-{0}(([1-9][\d]{0,7})(\.[0-9]{1,2})?|(0\.[1-9]{1,2})|(0\.0[1-9]{1})|(0\.[1-9]{1}0))$/,   //金额验证（不能为0）
		nickname	:/^[A-Za-z0-9\u4E00-\u9FA5]+$/,
		phoneMes	 : /^[0-9]{6}$/,
		newPasTip  :/^.{6,16}/,
	}
};
if("function"==typeof define && define.amd && define){
	define(['jquery','common/pccommons'],function($,pcCommon){
		return Validate($,pcCommon);
	});
}else{
	(function($){
		Validate($);
	})(jQuery);
}